using System;
using System.Collections.ObjectModel;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.Logging;
using SchoolApp_Material.Models;
using SchoolApp_Material.Msgs;

namespace SchoolApp_Material.ViewModels;

public class StudentMgrViewModel : ViewModelBase
{
    private ILogger<StudentMgrViewModel> _logger;
    private IFreeSql _freeSql;

    public StudentMgrViewModel()
    {
        if (!Design.IsDesignMode) return;
    }

    public StudentMgrViewModel(ILogger<StudentMgrViewModel> logger, IFreeSql freeSql)
    {
        if (Design.IsDesignMode) return;
        _logger = logger;
        _freeSql = freeSql;
        Pagination = new PaginationViewModel(ExecuteQueryCmd);
    }

    #region 属性

    private string _code;

    public string Code
    {
        get => _code;
        set => SetProperty(ref _code, value);
    }

    private string _name;

    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }

    private string _formYear;

    public string FormYear
    {
        get => _formYear;
        set => SetProperty(ref _formYear, value);
    }

    private string _formCode;

    public string FormCode
    {
        get => _formCode;
        set => SetProperty(ref _formCode, value);
    }

    private ObservableCollection<StudentViewModel> _studentList = [];

    public ObservableCollection<StudentViewModel> StudentList
    {
        get => _studentList;
        set => SetProperty(ref _studentList, value);
    }

    private PaginationViewModel _pagination;

    public PaginationViewModel Pagination
    {
        get => _pagination;
        set => SetProperty(ref _pagination, value);
    }

    #endregion

    #region 命令

    #region 查询

    private RelayCommand _queryCmd;

    public RelayCommand QueryCmd =>
        _queryCmd ??= new RelayCommand(ExecuteQueryCmd, CanExecuteQueryCmd);

    private void ExecuteQueryCmd()
    {
        StudentList.Clear();
        var iQuery = _freeSql.Select<Student>().Where(f => !f.IsDeleted);

        if (!string.IsNullOrEmpty(Code))
            iQuery = iQuery.Where(f => f.Code.Contains(Code));

        if (!string.IsNullOrEmpty(Name))
            iQuery = iQuery.Where(f => f.Name.Contains(Name));
        
        if (!string.IsNullOrEmpty(FormYear) && int.TryParse(FormYear, out var formYear))
            iQuery = iQuery.Where(f => f.FormYear == formYear);
        
        if (!string.IsNullOrEmpty(FormCode))
            iQuery = iQuery.Where(f => f.FormCode.Contains(FormCode));

        Pagination.RowCount = iQuery.Count();
        Pagination.PageCount = (int)Math.Ceiling((double)Pagination.RowCount / Pagination.PageSize);
        iQuery = iQuery.OrderByDescending(f => f.Id).Skip((Pagination.PageNo - 1) * Pagination.PageSize)
            .Take(Pagination.PageSize);
        var students = iQuery.ToList();
        if (students.Count > 0)
        {
            foreach (var student in students)
            {
                StudentList.Add(new StudentViewModel()
                {
                    Id = student.Id,
                    Code = student.Code,
                    Name = student.Name,
                    Sex = student.Sex,
                    BirthYear = student.BirthYear?.ToString(),
                    CreateOperatorCode = student.CreateOperatorCode,
                    CreateOperatorName = student.CreateOperatorName,
                    CreateTime = student.CreateTime,
                    EditAction = Edit,
                    DelAction = Delete
                });
            }
        }
    }

    private bool CanExecuteQueryCmd()
    {
        return true;
    }

    #endregion

    #region 新增

    private RelayCommand _addCmd;

    public RelayCommand AddCmd =>
        _addCmd ??= new RelayCommand(ExecuteAddCmd);

    private void ExecuteAddCmd()
    {
        WeakReferenceMessenger.Default.Send(new MsgBase<StudentViewModel>() { Data = new StudentViewModel() });
    }

    #endregion

    #endregion

    #region 方法

    private void Edit(StudentViewModel student)
    {
        WeakReferenceMessenger.Default.Send(new MsgBase<StudentViewModel>() { Data = student });
    }

    private void Delete(StudentViewModel student)
    {
        WeakReferenceMessenger.Default.Send(new StudentDelMsg()
        {
            Student = student, ConfirmAction = () =>
            {
                var rowCount = _freeSql.Update<Student>()
                    .Set(f => f.IsDeleted, true)
                    .Set(f => f.UpdateTime, DateTime.Now)
                    .Set(f => f.UpdateOperatorCode, Common.LoginOperator.Code)
                    .Set(f => f.UpdateOperatorName, Common.LoginOperator.Name)
                    .Where(f => f.Id == student.Id).ExecuteAffrows();
                _logger.LogInformation($"删除Student数据{rowCount}行");
                StudentList.Remove(student);
            }
        });
    }

    #endregion
}